home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / news / nntp / nntplink3.1.0 / batchfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-25  |  8.8 KB  |  360 lines

  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include "conf.h"
  4. #ifdef FAKESYSLOG
  5. #include "fsyslog.h"
  6. #else
  7. #include <syslog.h>
  8. #endif
  9. #ifdef HAVE_STRING_H
  10. #include <string.h>
  11. #else
  12. #include <strings.h>
  13. #endif
  14. #include <sys/stat.h>
  15. #include <sys/time.h>
  16. #include "readline.h"
  17. #include "nntplink.h"
  18. #include "strfuns.h"
  19.  
  20. extern char *E_fcntl;
  21. extern char *E_fopen;
  22. extern char *E_fseek;
  23. extern char *E_fstat;
  24. extern char *E_open;
  25. extern char *E_read;
  26. extern char *E_rename;
  27. extern char *E_unlink;
  28. extern char *E_write;
  29.  
  30. extern Boolean Abort_signaled;
  31. extern Boolean Debug;
  32. extern int Dtablesize;
  33. extern long Idle_time;
  34. extern int Input_from;
  35. extern Boolean One_shot;
  36. extern Boolean Reset_signaled;
  37.  
  38. extern void close_article();
  39. extern void check_sleep();
  40. extern Boolean parse_entry();
  41. extern void fail();
  42. extern void log();
  43.  
  44. int No_articles = 0;
  45.  
  46. void
  47.   check_batchfile()
  48. {
  49.     static char *fname = "check_batchfile: ";
  50.     struct stat statb;
  51.     int fd;
  52.  
  53.     Batchfile.use = FALSE;
  54.  
  55.     if (!One_shot) {
  56.  
  57.     if (stat(Batchfile.nname, &statb) != FAIL) {
  58.  
  59.         dlog(LOG_DEBUG, fname, "%sFound batchfile.nntp\n");
  60.  
  61.         if (statb.st_size == 0) {
  62.  
  63.         dlog(LOG_DEBUG, fname, "%sbatchfile.nntp is empty\n");
  64.  
  65.         if (unlink(Batchfile.nname) < 0)
  66.           fail(fname, E_unlink, Host.name, Batchfile.nname,
  67.                errmsg(errno));
  68.         } else {
  69.  
  70.         if ((fd = open(Batchfile.nname, O_RDONLY)) == FAIL)
  71.           fail(fname, E_open, Host.name, Batchfile.nname, "r",
  72.                errmsg(errno));
  73.  
  74.         Batchfile.use = TRUE;
  75.         Batchfile.nntp_in_use = TRUE;
  76.         Batchfile.fbp = fb_fdopen(fd);
  77.         if ((statb.st_ino == Batchfile.inode) &&
  78.             (Batchfile.offset != 0) &&
  79.             (fb_seek(Batchfile.fbp, Batchfile.offset, 0) == FAIL))
  80.           log(LOG_WARNING, fname, E_fseek, Host.name, Batchfile.nname,
  81.               errmsg(errno));
  82.         else
  83.           Batchfile.inode = statb.st_ino;
  84.         return;
  85.         }
  86.     }
  87.  
  88.     if (Input_from & FLG_BATCHFILE) {
  89.  
  90.         dlog(LOG_DEBUG, fname, "%swaiting for batchfile: ");
  91.  
  92.         while (stat(Batchfile.name, &statb) == FAIL)
  93.           check_sleep(Batchfile.nap_time, CREATE_BATCH);
  94.  
  95.         dlog(LOG_DEBUG, "", "%sGot it\n");
  96.     }
  97.     }
  98.  
  99.     if ((stat(Batchfile.name, &statb) != FAIL) &&
  100.     ((Input_from & FLG_BATCHFILE) || !One_shot)) {
  101.  
  102.     dlog(LOG_DEBUG, fname, "%sFound batchfile\n");
  103.  
  104.     if (Input_from & FLG_BATCHFILE) {
  105.  
  106.         if ((fd = open(Batchfile.name, O_RDONLY)) == FAIL)
  107.           fail(fname, E_open, Host.name, Batchfile.name, "r",
  108.            errmsg(errno));
  109.  
  110.         Batchfile.fbp = fb_fdopen(fd);
  111.         Batchfile.use = TRUE;
  112.         if ((statb.st_ino == Batchfile.inode) &&
  113.         (Batchfile.offset != 0) &&
  114.         (fb_seek(Batchfile.fbp, Batchfile.offset, 0) == FAIL))
  115.           log(LOG_WARNING, fname, E_fseek, Host.name, Batchfile.name,
  116.           errmsg(errno));
  117.         else
  118.           Batchfile.inode = statb.st_ino;
  119.         return;
  120.  
  121.     } else {
  122.         if (statb.st_size == 0) {
  123.  
  124.         dlog(LOG_DEBUG, fname, "%sbatchfile is empty - removing\n");
  125.  
  126.         if (unlink(Batchfile.name) < 0)
  127.           dlog(LOG_WARNING, fname, E_unlink, Host.name, Batchfile.name,
  128.                errmsg(errno));
  129.  
  130.         } else {
  131.  
  132.         dlog(LOG_DEBUG, fname,
  133.              "%srenaming batchfile to batchfile.nntp\n");
  134.  
  135.         if (rename(Batchfile.name, Batchfile.nname) == FAIL)
  136.           fail(fname, E_rename, Host.name, Batchfile.name,
  137.                Batchfile.nname, errmsg(errno));
  138.  
  139.         check_batchfile();
  140.         return;
  141.         }
  142.     }
  143.     }
  144.     if (One_shot && (Input_from & FLG_BATCHFILE))
  145.       fail(fname, "%s%s: %s not found on a One-shot\n", Host.name,
  146.        Batchfile.name);
  147.  
  148.     return;
  149. }
  150.  
  151.  
  152. void
  153.   update_batchfile()
  154. {
  155.     static char *fname = "update_batchfile: ";
  156.     char *entry, *filename = NULL, *mesgid = NULL;
  157.     struct stat batch_stat, log_stat;
  158.     FILE *tfp;
  159.     int fd, bytes_read = 0;
  160. #ifdef HAVE_SELECT
  161.     fd_set readfds;
  162.     static struct timeval timeout = {0, 0};
  163. #endif
  164.  
  165.     No_articles = 0;
  166.  
  167.     if (Reset_signaled && (Input_from & FLG_LOGFILE))
  168.       log(LOG_INFO, fname, "%s%s: Resetting to use new logfile\n", Host.name);
  169.  
  170.     if (Debug)
  171.       if (Input_from & FLG_LOGFILE)
  172.     log(LOG_DEBUG, fname, "%sUpdating Batchfile from Logfile\n");
  173.       else
  174.     log(LOG_DEBUG, fname, "%sUpdating Batchfile from <stdin>\n");
  175.  
  176.     /* First we want to clean up the old batchfile */
  177.     if ((Batchfile.fbp != NULL) && (Reset_signaled || Abort_signaled)) {
  178.  
  179.     if ((tfp = fopen(Batchfile.tmp, "w")) == NULL)
  180.       fail(fname, E_fopen, Host.name, Batchfile.tmp, "w", errmsg(errno));
  181.  
  182.     fd = fb_fileno(Batchfile.fbp);
  183.  
  184.     if (Article.filename != NULL) {
  185.         No_articles++;
  186. #ifdef BNEWS
  187.         fprintf(tfp, "%s\t%s\t%d\n", Article.filename, Article.mesgid,
  188.             Article.count);
  189. #else
  190.         fprintf(tfp, "%s %s %d\n", Article.filename, Article.mesgid,
  191.             Article.count);
  192. #endif
  193.         close_article();
  194.     }
  195.  
  196.     while ((entry = fb_readline(Batchfile.fbp, NULL)) != NULL) {
  197.         No_articles++;
  198.         if (fprintf(tfp, "%s\n", entry) == FAIL)
  199.           fail(fname, E_write, Host.name, Batchfile.tmp, errmsg(errno));
  200.     }
  201.  
  202.     FCLOSE(tfp);
  203.     close(fb_fileno(Batchfile.fbp));
  204.     fb_close(Batchfile.fbp);
  205.     Batchfile.fbp = NULL;
  206.     Batchfile.offset = Batchfile.inode = 0;
  207.  
  208.     if (rename(Batchfile.tmp, Batchfile.nname) == FAIL)
  209.       fail(fname, E_rename, Host.name, Batchfile.tmp, Batchfile.nname,
  210.            errmsg(errno));
  211.     }
  212.  
  213.     if ((tfp = fopen(Batchfile.nname, "a")) == NULL)
  214.       fail(fname, E_fopen, Host.name, Batchfile.nname, "a", errmsg(errno));
  215.  
  216.     if (Article.filename != NULL) {
  217.     No_articles++;
  218. #ifdef BNEWS
  219.     fprintf(tfp, "%s\t%s\t%d\n", Article.filename, Article.mesgid,
  220.         Article.count);
  221. #else
  222.     fprintf(tfp, "%s %s %d\n", Article.filename, Article.mesgid,
  223.         Article.count);
  224. #endif
  225.     close_article();
  226.     }
  227.  
  228.     if (Input_from & FLG_LOGFILE) {
  229.  
  230.     if (Logfile.fbp != NULL) {
  231. #ifdef LOOKUP_ARTICLE
  232.         Article.filename = strsave("/");
  233. #endif
  234.         while ((entry = fb_readline(Logfile.fbp, NULL)) != NULL)
  235.           if (parse_entry(entry)) {
  236.           No_articles++;
  237. #ifdef BNEWS
  238.           fprintf(tfp, "%s\t%s\n", Article.filename, Article.mesgid);
  239. #else
  240.           fprintf(tfp, "%s %s\n", Article.filename, Article.mesgid);
  241. #endif
  242.           }
  243.  
  244.         if (fb_error(Logfile.fbp))
  245.           log(LOG_INFO, fname, E_read, Host.name,
  246.           Logfile.name, errmsg(errno));
  247.  
  248. #ifdef LOOKUP_ARTICLE
  249.         free(Article.filename);
  250. #endif
  251.  
  252.         Article.filename = Article.mesgid = NULL;
  253.  
  254.         Logfile.offset = fb_tell(Logfile.fbp);
  255.         close(fb_fileno(Logfile.fbp));
  256.         fb_close(Logfile.fbp);
  257.         Logfile.fbp = NULL;
  258.     }
  259.  
  260.     (void) fflush(tfp);
  261.  
  262.     if (ferror(tfp))
  263.       fail(fname, "%s%s: copy to batchfile.nntp failed: %s\n", Host.name,
  264.            errmsg(errno));
  265.  
  266.     FCLOSE(tfp);
  267.  
  268.     while ((fd = open(Logfile.name, O_RDONLY)) == FAIL)
  269.       check_sleep(Logfile.nap_time, CREATE_BATCH);
  270.  
  271.     Logfile.fbp = fb_fdopen(fd);
  272.  
  273.     if (fstat(fd, &log_stat) == FAIL)
  274.       fail(fname, E_fstat, Host.name, Logfile.name, errmsg(errno));
  275.     else
  276.       if (Logfile.inode == log_stat.st_ino) {
  277.           if (fb_seek(Logfile.fbp, Logfile.offset, 0) == FAIL)
  278.         log(LOG_WARNING, fname, E_fseek, Host.name, Logfile.name,
  279.             errmsg(errno));
  280.       } else
  281.         Logfile.inode = log_stat.st_ino;
  282.  
  283.     } else {                /* Input_from & FLG_STDIN */
  284.       
  285.       if ((Article.filename != NULL) && Abort_signaled) {
  286. #ifdef BNEWS
  287.     fprintf(tfp, "%s\t%s\n", Article.filename, Article.mesgid);
  288. #else
  289.     fprintf(tfp, "%s %s\n", Article.filename, Article.mesgid);
  290. #endif
  291.       } else {
  292.  
  293.     filename = Article.filename;
  294.     mesgid = Article.mesgid;
  295.       }
  296.  
  297.       while((entry = fb_readline(Stdin, NULL)) != NULL)
  298.     if (parse_entry(entry)) {
  299.       No_articles++;
  300. #ifdef BNEWS
  301.       fprintf(tfp, "%s\t%s\n", Article.filename, Article.mesgid);
  302. #else
  303.       fprintf(tfp, "%s %s\n", Article.filename, Article.mesgid);
  304. #endif
  305.     }
  306.  
  307.       Article.filename = filename;
  308.       Article.mesgid = mesgid;
  309.  
  310.       if (fb_error(Stdin) && (errno != READ_ERROR))
  311.     log(LOG_INFO, fname, "%s%s: error reading stdin: %s\n", Host.name,
  312.         errmsg(errno));
  313.  
  314.       (void) fflush(tfp);
  315.  
  316.       if (ferror(tfp))
  317.     fail(fname, "%s%s: copy to batchfile.nntp failed: %s\n", Host.name,
  318.          errmsg(errno));
  319.  
  320.       FCLOSE(tfp);
  321.  
  322.     }
  323.  
  324.     Batchfile.use = Batchfile.nntp_in_use = FALSE;
  325.  
  326.     if (stat(Batchfile.nname, &batch_stat) != FAIL)
  327.       if (batch_stat.st_size == 0) {
  328.     if (unlink(Batchfile.nname) == FAIL)
  329.       log(LOG_WARNING, fname, E_unlink, Host.name, Batchfile.nname,
  330.           errmsg(errno));
  331.       } else {
  332.     if (Batchfile.fbp == NULL) {
  333.       if ((fd = open(Batchfile.nname, O_RDONLY)) == FAIL)
  334.         fail(fname, E_fopen, Host.name, Batchfile.nname, "r",
  335.          errmsg(errno));
  336.  
  337.       if (Debug && !Abort_signaled)
  338.         log(LOG_DEBUG, fname, "%s%s: Switching to Batchfile.nntp\n",
  339.         Host.name);
  340.  
  341.       Batchfile.fbp = fb_fdopen(fd);
  342.     }
  343.     Batchfile.use = Batchfile.nntp_in_use = TRUE;
  344.       }
  345.  
  346.     if ((Input_from & FLG_STDIN) && fb_eof(Stdin) && !Abort_signaled) {
  347.       log(LOG_INFO, fname, "%s%s: EOF on stdin, exiting\n", Host.name);
  348.       Abort_signaled = TRUE;
  349.     } else if (Reset_signaled || Abort_signaled)
  350.       if (No_articles > 1)
  351.     log(LOG_INFO, fname, "%s%s: Batchfile Updated, %d articles queued\n",
  352.         Host.name, No_articles);
  353.       else
  354.     log(LOG_INFO, fname, "%s%s: Batchfile Updated, No articles queued\n",
  355.         Host.name);
  356.  
  357.     Reset_signaled = FALSE;
  358.     return;
  359. }
  360.